package team.bluepen.supermarket.data.dao;

import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.util.Bytes;
import team.bluepen.supermarket.constant.Error;
import team.bluepen.supermarket.data.dao.abstraction.DeleteOperate;
import team.bluepen.supermarket.data.entity.HbaseItem;
import team.bluepen.supermarket.data.hbase.HTableRunner;
import team.bluepen.supermarket.util.Log;
import team.bluepen.supermarket.util.StringUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 实现 {@link DeleteOperate} 接口
 * @author Kai
 */
public class DeleteRunner<T extends HbaseItem<T>> implements DeleteOperate<T> {
    private static final String TAG = "DeleteRunner";
    private final Admin admin;
    private final HTable table;
    private final TableName name;

    public DeleteRunner(Admin admin, HTable table) {
        this.admin = admin;
        this.table = table;
        this.name = table.getName();
    }

    @Override
    public Error delete() {
        try (HTableRunner runner = new HTableRunner(table)) {
            if (admin.isTableDisabled(name)) {
                return Error.ERROR_TABLE_DISABLED;
            }
            return runner.truncate();
        } catch (IOException e) {
            return Error.ERROR_DATABASE;
        }
    }

    @Override
    public Error delete(String row) {
        try {
            if (!admin.tableExists(name)){
                return Error.ERROR_TABLE_NOT_EXIST;
            }
            if (admin.isTableDisabled(name)) {
                return Error.ERROR_TABLE_DISABLED;
            }
        } catch (IOException e) {
            Log.e(TAG, e);
            return Error.ERROR_DATABASE;
        }

        if (StringUtil.isEmpty(row)){
            return Error.ERROR_NULL;
        }
        Delete delete = new Delete(Bytes.toBytes(row));
        try {
            table.delete(delete);
            return Error.SUCCESS;
        } catch (IOException e) {
            Log.e(TAG, e);
            return Error.ERROR_DATABASE;
        }
    }

    @Override
    public Error delete(T t) {
        return delete(t.getRow());
    }

    @Override
    public Error delete(List<T> t) {
        try {
            if (!admin.tableExists(name)){
                return Error.ERROR_TABLE_NOT_EXIST;
            }
            if (admin.isTableDisabled(name)) {
                return Error.ERROR_TABLE_DISABLED;
            }
        } catch (IOException e) {
            Log.e(TAG, e);
            return Error.ERROR_DATABASE;
        }

        if (t == null) {
            return Error.ERROR_NULL;
        }
        List<Delete> deletes = new ArrayList<>();
        for (T u: t){
            deletes.add(new Delete(Bytes.toBytes(u.getRow())));
        }
        try {
            table.delete(deletes);
            return Error.SUCCESS;
        } catch (IOException e) {
            Log.e(TAG, e);
            return Error.ERROR_DATABASE;
        }
    }

    @Override
    public Error delete(String row, String family) {
        try {
            if (!admin.tableExists(name)){
                return Error.ERROR_TABLE_NOT_EXIST;
            }
            if (admin.isTableDisabled(name)) {
                return Error.ERROR_TABLE_DISABLED;
            }
        } catch (IOException e) {
            Log.e(TAG, e);
            return Error.ERROR_DATABASE;
        }

        if (StringUtil.isEmpty(family) || StringUtil.isEmpty(row)) {
            return Error.ERROR_NULL;
        }

        Delete delete = new Delete(Bytes.toBytes(row));
        delete.addFamily(Bytes.toBytes(family));
        try {
            table.delete(delete);
            return Error.SUCCESS;
        } catch (IOException e) {
            Log.e(TAG, e);
            return Error.ERROR_DATABASE;
        }
    }
}
